﻿//*************************************************************************
//面向服务的协作式智能交通系统仿真软件SoC-ITSS v2.1 alpha
//发布单位：西北工业大学--巴黎高科MINES机器人与群智能系统联合实验室
//团队负责人：张凯龙 Zhang Kailong
//团队成员：张大方、杨安胜、王敏、谢策、王雨佳、谢尘玉等
//联系我们：kl.zhang@nwpu.edu.cn
//2012-2021
//*************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using CyberCarSimulation.Bean;
using CyberCarSimulation.RoadModel;
using CyberCarSimulation.Regulation;
using CyberCarSimulation.Simulation;

//*******************************************************
//
//文件名(File Name):           MultiSCSFIFO_Sche.cs
//
//数据表(Tables):              nothing 
//
//          修改理由：         调度执行每一个Agent的算法 FAFP-SV
//
//*******************************************************


namespace CyberCarSimulation.Algorithm
{
    class MultiSCSFIFO_Sche
    {
        private string ID;        //Agent的ID,此ID与路口ID相同
        private int IDNum;        //第几个Agent的Num号

        private int MsgCount = 0;   //发送至车辆的消息数量

        /************************************************************************/
        /* 发出申请消息之后的车辆的数据信息                                                                     */
        /************************************************************************/
        //键值对，用于存储申请该临界区的车辆的VehicleManager信息，取用方式为<车辆的ID，车辆对应的CS消息>，其中每一条队列既是一个临界区所对应的CS消息
        private List<KeyValuePair<string, VehicleManager>>[] CS = new List<KeyValuePair<string, VehicleManager>>[5];
        //各车道的队列，存储各车道申请临界区的车辆的SuperVehicleManager信息，对应于4个车道（过了预约线之后加入）
        private List<SuperVehicleManager>[] LaneQueue = new List<SuperVehicleManager>[5];       


        /************************************************************************/
        /* 当前已授权车辆的信息，此处只存储其车辆和临界区消息，不存储具体的消息                                                                     */
        /************************************************************************/
        //键值对，<CSID，ID>用于记录将编号为CSID的S-CS资源授权给编号为ID的车辆,其数目最多为4 ，对应于4个临界区
        public Dictionary<int, string> Authorize_CS_to_Vehicle = new Dictionary<int, string>();
        //保存当前被授权的车辆ID号，  其数量最多为4，代表一个时间段之内最多只有4辆车被授权
        private List<string> Authorized_Vehicle_Sequence = new List<string>();
        //保存之前已经被授权完成的车辆这些车辆无需再被授权
        private List<string> Already_Authorized_All_CS_Vehicles = new List<string>();

        //Token[XXX]为true表示编号为XXX的S-CS资源已经被占用，为false则表示该资源空闲
        private bool[] Token = new bool[5];

        //用于分辨是否会产生死锁
        private bool[] Walked = new bool[5];
        private bool[,] SourceGraph = new bool[5, 5];

        //构造函数初始化变量
        public MultiSCSFIFO_Sche(string ID)
        {
            //设置ID
            this.ID = ID;
            this.IDNum = int.Parse(ID.Substring(3, 2));

            //第一个路口初始化
            for (int i = 0; i < 5; i++)
            {
                this.Token[i] = false;
                this.CS[i] = new List<KeyValuePair<string, VehicleManager>>();
                this.LaneQueue[i] = new List<SuperVehicleManager>();
            }
        }


        /************************************************************************/
        /* MultiSCSFIFO_Sche对象的对外接口，用于执行FIFO调度算法                                                                     */
        /************************************************************************/
        public void executeAlgorithm(Intersection Intersection)
        {
            //读入消息
            this.readMessageFromVehicle(Intersection);
            //对临界区进行分配
            this.processLeftVehicles(Intersection);

            for (int i = 0; i < 5; ++i)
            {
                for (int j = 0; j < this.CS[i].Count; ++j)
                {
                    this.CS[i].ElementAt(j).Value.isSelect = false;
                }
            }
        }

        //处理LaneQueue的存放问题，之前全部存放到LaneQueue[4]中
        //取代str[0]设计


        /************************************************************************/
        /* 从Msg_Buffer类的存储空间中读取相关信息，如Msg_Reservation消息、Msg_Release消息等。  
         * string IntersectionID 为当前处理的路口的ID
        /************************************************************************/
        private void readMessageFromVehicle(Intersection Intersection)
        {

            //获取路口中的消息队列
            List<Message> VtoA_BufferTemp = Intersection.GetVtoA_Buffer();    //局部变量，需要重新写回去
            
            //遍历消息队列，对消息处理
            while (VtoA_BufferTemp.Count != 0)
            {
                //取出一条Message
                Message m = VtoA_BufferTemp.ElementAt(0);
                VtoA_BufferTemp.Remove(m);

                switch (m.GetType())
                {
                    //在预约消息下需要创建新消息，并将消息存入不同的队列中
                    case Definitions.MsgReservation:
                        SuperVehicleManager svm;
                        string LaneIDTemp = m.GetLaneIDStr();
                        svm = new SuperVehicleManager(m.GetSender(), int.Parse(LaneIDTemp.Substring(5, 1)), m.GetTsArray(), m.GetTeArray(),
                                            m.GetTotal_Dis(), m.GetSectionID(), m.GetPriority());
                        /*将生成的车辆管理实体加入到对应的队列中*/
                        //因为进入车道的车辆本身具有具有顺序，所以此处无需对车道按照车辆插入时间对车辆进行排序
                        this.LaneQueue[svm.LaneID].Add(svm);
                        this.updateCSQueue(svm);
                        this.sortCSQueue();
                        break;
                    case Definitions.MsgFault:
                        break;
                    case Definitions.MsgWait:
                        break;
                    case Definitions.MsgRenew:
                        //主要用于更新车辆到达时间
                        string str = m.GetLaneIDStr();  //车辆的ID
                        string section = m.GetSectionID();
                        float[] ts = m.GetTsArray();
                        float[] te = m.GetTeArray();
                        for (int i = 0; i < this.LaneQueue[int.Parse(str[5].ToString())].Count(); ++i)
                        {
                            if (this.LaneQueue[int.Parse(str[5].ToString())].ElementAt(i).getID() == m.GetSender())
                            {
                                this.LaneQueue[int.Parse(str[5].ToString())].ElementAt(i).setTs(m.GetTsArray());
                                this.LaneQueue[int.Parse(str[5].ToString())].ElementAt(i).setTe(m.GetTeArray());

                            }
                        }

                        for (int j = 0; j < section.Length; j++)
                        {
                            foreach (KeyValuePair<string, VehicleManager> kvp in this.CS[int.Parse(section[j].ToString())])
                            {
                                if (kvp.Key == m.GetSender())
                                {
                                    kvp.Value.setTs(ts[j + 1]);
                                    kvp.Value.setTe(te[j + 1]);
                                }
                            }
                        }
                        this.sortCSQueue();
                        break;
                    case Definitions.MsgRelease:
                        /*释放对应的SCS*/
                        //将对应的临界区的消息去除
                        str = m.GetSender();

                        Vehicle VehicleTemp = FindVehicleByID(str);
                        string Lanestr = VehicleTemp.Get_Previous_LaneID();

                        //CS信息，若释放，则删除对应的临界区
                        foreach (KeyValuePair<string, VehicleManager> kvp in this.CS[int.Parse(m.GetSectionID().ToString())])
                        {
                            if (kvp.Key == m.GetSender())
                            {
                                this.CS[int.Parse(m.GetSectionID().ToString())].Remove(kvp);
                                break;
                            }
                        }
                        //LaneQueue信息，若释放，则将对应的临界区的token信息，left信息更新，其中HaveTokenCount因为其已被申请过，所以不作修改
                        for (int i = 0; i < this.LaneQueue[int.Parse(Lanestr[5].ToString())].Count(); ++i)
                        {
                            if (this.LaneQueue[int.Parse(Lanestr[5].ToString())].ElementAt(i).getID() == m.GetSender())
                            {
                                this.LaneQueue[int.Parse(Lanestr[5].ToString())].ElementAt(i).Token[int.Parse(m.GetSectionID().ToString())] = false;
                                this.LaneQueue[int.Parse(Lanestr[5].ToString())].ElementAt(i).Left[int.Parse(m.GetSectionID().ToString())] = true;
                            }
                        }

                        //将被占用临界区标志位为未被占用
                        this.Token[int.Parse(m.GetSectionID().ToString())] = false;
                        this.Authorize_CS_to_Vehicle.Remove(int.Parse(m.GetSectionID().ToString()));
                        //this.OutPutAuthMsg(2, m);
                        break;
                    case Definitions.MsgPassing:
                        //标志车辆正在经过某临界区，无需处理
                        break;
                    case Definitions.MsgPassed:
                        //车辆离开十字路口
                        this.removePassedVehicle(m.GetSender());
                        break;
                    default:
                        System.Windows.Forms.MessageBox.Show("Unknown Message Type ------ " + m.GetType(), "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                        break;
                }
            }

            //将数据写会MainData中
            Intersection.SetVtoA_Buffer(VtoA_BufferTemp);
            MainData.UpdateIntersectionList(Intersection);
        }


        /************************************************************************/
        /* 更新个临界区的消息队列                                                                     */
        /************************************************************************/
        private void updateCSQueue(SuperVehicleManager svm)
        {
            for (int i = 1; i < 5; i++)
            {
                if (svm.VehicleManagers[i] != null)
                {
                    VehicleManager vm = svm.VehicleManagers[i];

                    //设置需要临界区的个数
                    vm.setCSCount(svm.VehicleManagers[i].getCSCount());

                    //更新临界区的消息队列
                    KeyValuePair<string, VehicleManager> kvp = new KeyValuePair<string, VehicleManager>(vm.getID(), vm);
                    this.CS[int.Parse(vm.getSectionIDs())].Add(kvp);
                }
            }
        }


        /************************************************************************/
        /* 将各临界区的申请车辆按照到达时间的先后顺序进行排序                                                                     */
        /************************************************************************/
        private void sortCSQueue()
        {
            for (int i = 1; i < 5; i++)
            {
                if (this.CS[i].Count != 0)
                {

                    //使用i和j，对CS中申请的车辆，按到达时间的先后排序
                    for (int j = 0; j < this.CS[i].Count; j++)
                    {
                        for (int k = j + 1; k < this.CS[i].Count; k++)
                        {
                            if (this.CS[i].ElementAt(j).Value.getTs() > this.CS[i].ElementAt(k).Value.getTs())
                            {
                                KeyValuePair<string, VehicleManager> kvp;
                                kvp = this.CS[i].ElementAt(j);
                                this.CS[i][j] = this.CS[i].ElementAt(k);
                                this.CS[i][k] = kvp;
                            }
                        }
                    }
                }
            }
        }


        /************************************************************************/
        /* 将过了临界区的车辆删除，并释放占用的资源,
         * ID为车辆的编号                                                                     */
        /************************************************************************/
        private void removePassedVehicle(string ID)
        {
            Vehicle VehicleTemp = FindVehicleByID(ID);
            string LaneIDPrevious = VehicleTemp.Get_Previous_LaneID(); //车辆之前所在的车道序号

            int LaneID = int.Parse(LaneIDPrevious[5].ToString());
            if (this.LaneQueue[LaneID].Count == 0) //判断车道对应的LaneQueue中是否为空
            {
                return;
            }
            
            //删除车道车辆列表中的车辆
            foreach (SuperVehicleManager stmp in LaneQueue[LaneID])
            {
                if (stmp.ID == ID)
                {
                    this.LaneQueue[LaneID].Remove(stmp);
                    break;
                }
            }
            //将申请过临界区的车辆释放
            for (int i = 1; i < 5; i++)
            {
                foreach (KeyValuePair<string, VehicleManager> kvp in this.CS[i])
                {
                    if (kvp.Key == ID)
                    {
                        this.CS[i].Remove(kvp);
                        break;
                    }
                }
            }
            //将授权过的的车辆释放
            for (int i = 0; i < Authorized_Vehicle_Sequence.Count; ++i)
            {
                if (this.Authorized_Vehicle_Sequence.ElementAt(i) == ID)
                {
                    this.Authorized_Vehicle_Sequence.RemoveAt(i);
                }
            }
            //将授权过的临界区的释放
            for (int i = 1; i < 5; i++)
            {
                if (this.Authorize_CS_to_Vehicle.ContainsKey(i) == true)
                {
                    if (this.Authorize_CS_to_Vehicle[i] == ID)
                    {
                        this.Authorize_CS_to_Vehicle.Remove(i);
                        break;
                    }
                }
            }
            return;
        }
        
       
        /************************************************************************/
        /* 对车辆进行授权                                                       */
        /************************************************************************/
        private void processLeftVehicles(Intersection Intersection)
        {
            //string s = null;

            //被授权车辆超过4辆
            if (this.Authorized_Vehicle_Sequence.Count > 4)
            {
                System.Windows.Forms.MessageBox.Show("the num of authorized vehicle is more than 4");
                return;
            }

            //s = null;
            if (!IsCSEmpty())
            {
                //若存在临界区未被占用
                VehicleManager vtmp = null;
                while ((vtmp = this.GetEarliestFromCSVehicle()) != null)
                {
                    //临界区分配完毕，则退出
                    if (this.Token[1] == true && this.Token[2] == true && this.Token[3] == true && this.Token[4] == true)
                    {
                        break;
                    }

                    //被选中车辆的CSID
                    int CSID = int.Parse(vtmp.getSectionIDs());
                    //被选中车辆的ID
                    string ID = vtmp.getID();

                    //找到车辆Vehicle对象的LaneID                        
                    string LaneID = FindVehicleByID(ID).Get_Current_LaneID();  

                    //临界区已被选中
                    if (this.Token[CSID] == true)
                    {
                        continue;
                    }


                    //判断顺序授权和是否为第一辆车
                    if (ID != null
                        && (this.isTokenSequenceIllegal(int.Parse(LaneID[5].ToString()), ID, CSID) == false)
                        && (this.isFirstVehicleInLane(int.Parse(LaneID[5].ToString()), ID, CSID) == true))
                    {

                        this.Authorize_CS_to_Vehicle.Add(CSID, ID);
                        if (this.isTokenSequenceDeadLock(this.Authorize_CS_to_Vehicle) != true)//不会死锁
                        {


                            //若车辆被授予临界区，但是未被授予所有临界区，那么就将该车存入Authorized_Vehicle_Sequence，
                            if (this.Authorize_CS_to_Vehicle.Keys.Contains(CSID))
                            {
                                if (this.Authorize_CS_to_Vehicle[CSID] == ID)
                                {

                                }
                                else
                                {
                                    System.Windows.Forms.MessageBox.Show("Authorize_CS_to_Vehicle error4");
                                }
                            }
                            else
                            {
                                this.Authorize_CS_to_Vehicle.Add(CSID, ID);
                            }

                            //给Agent发送Message消息
                            this.sendMessage(Definitions.MsgAuthorize, ID, vtmp.getCurrentPriority(), CSID, Intersection);

                            //设置授权信息
                            this.setToken(CSID, ID);

                            //判断当前被授权车辆是否还有未申请的临界区
                            SuperVehicleManager stmp = null;
                            int kkkk = 0;
                            for (int i = 1; i < 5; ++i)
                            {
                                for (int j = 0; j < this.LaneQueue[i].Count; ++j)
                                {
                                    if (this.LaneQueue[i].ElementAt(j).ID == ID)
                                    {
                                        stmp = this.LaneQueue[i].ElementAt(j);
                                        for (kkkk = 0; kkkk < stmp.CS_Count; kkkk++)
                                        {
                                            if (stmp.Token[int.Parse(stmp.SectionID[kkkk].ToString())] == false)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            //若车辆未申请完成所有临界区，则将其存入Authorized_Vehicle_Sequence中，作为当前仍需申请临界区的车辆对待
                            if (kkkk != vtmp.getCSCount())
                            {
                                if (stmp != null)
                                {
                                    bool mark = false;
                                    for (int k = 0; k < this.Authorized_Vehicle_Sequence.Count; k++)
                                    {
                                        if (this.Authorized_Vehicle_Sequence[k] == stmp.ID)
                                        {
                                            mark = true;
                                        }
                                    }
                                    if (mark == false)
                                    {
                                        this.Authorized_Vehicle_Sequence.Add(stmp.ID);
                                    }
                                }
                            }
                            else
                            {//该车辆已经申请完成所有的临界区，无需再次判断

                                bool mark = false;
                                for (int k = 0; k < this.Authorized_Vehicle_Sequence.Count; k++)
                                {
                                    if (this.Authorized_Vehicle_Sequence[k] == stmp.ID)
                                    {
                                        mark = true;
                                    }
                                }
                                if (mark == false)
                                {
                                    this.Authorized_Vehicle_Sequence.Add(stmp.ID);
                                }
                                this.Already_Authorized_All_CS_Vehicles.Add(stmp.ID);
                            }
                        }
                        else    //会产生死锁
                        {
                            this.Authorize_CS_to_Vehicle.Remove(CSID);
                        }
                    }
                }
            }
        }


        /************************************************************************/
        /* 判断各临界区的申请队列是否为空                                                                     */
        /************************************************************************/
        private bool IsCSEmpty()
        {
            bool mark = true;
            for (int i = 1; i < 5; ++i)
            {
                if (this.CS[i].Count != 0)
                {
                    mark = false;
                }
            }
            return mark;
        }


        /************************************************************************/
        /* 获取各个道路列表中最早到达的车辆,用于每次先进行判断的车辆，返回车辆的ID号                                                                     */
        /************************************************************************/
        private VehicleManager GetEarliestFromCSVehicle()
        {
            VehicleManager vtmp = null;
            VehicleManager SelTmp = null;
            float EarliestTime = 99999.0f;
            int ChosenCS = 0;       //标志所选中的CS号
            int ChosenVehi = 0;     //标志所选中车道中的车辆的ID号

            for (int i = 1; i < 5; ++i)
            {
                if (this.Token[i] == false)
                {
                    for (int j = 0; j < this.CS[i].Count; ++j)
                    {
                        vtmp = this.CS[i].ElementAt(j).Value;
                        string str = vtmp.getID();

                        //通过时间判断车辆是否到达临界区，如果TS时间大于全局时间，说明车辆还没到达临界区
                        //if ((vtmp.getTs() - Main.getGlobalTime()) <= 0.00000000001f)
                        float temp = vtmp.getTs() - Main.getGlobalTime();
                        if (temp < 0)   //精度调大了
                        {
                            //车辆已经经过临界区了
                            Debug.Write("车辆已经经过临界区了");
                            continue;
                        }

                        if (Already_Authorized_All_CS_Vehicles.Contains(str))
                        {
                            //车辆的所有临界区已被授权
                            Debug.Write("车辆的所有临界区已被授权");
                            continue;
                        }
                        else
                        {
                            //车辆未被选中授权,则进行车辆的选择
                            if (vtmp.isSelect == false)
                            {
                                if ((EarliestTime - vtmp.getTs()) > 0.00000000001f)
                                {
                                    ChosenCS = i;
                                    ChosenVehi = j;
                                    EarliestTime = vtmp.getTs();
                                    SelTmp = vtmp;
                                }
                            }
                        }

                    }
                }
                else
                {

                }
            }
            if (SelTmp != null)
            {
                this.CS[ChosenCS].ElementAt(ChosenVehi).Value.isSelect = true;
            }

            return SelTmp;
        }

        /************************************************************************/
        /* 检验在道路消息队列组中的某一辆车是否，判断一辆是否是按照临界区先后循序进行申请的，返回true则非法                                                                     */
        /************************************************************************/
        private bool isTokenSequenceIllegal(int LaneID, string ID, int AuthCSID)
        {
            SuperVehicleManager svm = null;
            int d = 0;

            //获取道路消息队列组中需要进行判断的车辆的总消息
            for (int i = 0; i < this.LaneQueue[LaneID].Count; i++)
            {
                if (this.LaneQueue[LaneID].ElementAt(i).ID == ID)
                {
                    svm = this.LaneQueue[LaneID].ElementAt(i);
                    break;
                }
            }

            if (svm != null)
            {
                //获取当前需要判断的临界区(是第几个)，即将要处理的临界区
                for (int i = 0; i < svm.CS_Count; i++)
                {
                    if (svm.VehicleManagers[int.Parse(svm.SectionID[i].ToString())] == null)
                    {
                        System.Windows.Forms.MessageBox.Show("error,isTokenSequenceIllegal1");
                        continue;
                    }
                    if (int.Parse(svm.SectionID[i].ToString()) == AuthCSID)
                    {
                        d = i;
                        break;
                    }
                }

                //将d之前的临界区判断一遍，看看是否都已经被授权了
                for (int i = 0; i < d; i++)
                {
                    //消息按照临界区序号进行存储
                    if (svm.VehicleManagers[int.Parse(svm.SectionID[i].ToString())] == null)
                    {
                        System.Windows.Forms.MessageBox.Show("error,isTokenSequenceIllegal2");
                        continue;
                    }
                    //车辆的所申请临界区之前的临界区已经申请完成，且所申请临界区该临界区还未申请成功，此时则说明合法
                    if (svm.VehicleManagers[int.Parse(svm.SectionID[i].ToString())].HasToken == false)
                    {

                        return true;
                    }
                }
            }
            else
            {

            }
            return false;
        }

        /************************************************************************/
        /* 检验当前授权车辆是否是道路中的第一辆车,若是首车，则返回true                                                                     */
        /************************************************************************/
        private bool isFirstVehicleInLane(int LaneID, string ID, int CSID)
        {
            SuperVehicleManager ktmp;
            string scs = null;
            int k = 0;
            int k2 = 1;
            //找到正在判断的车辆
            foreach (SuperVehicleManager kvp in LaneQueue[LaneID])
            {
                if (kvp.ID == ID)
                {
                    ktmp = kvp;
                    scs = ktmp.Original_SectionID;
                    break;
                }
                ++k;
            }
            //正在判断中车辆所申请临界区在其所用临界区中所处的位置
            for (int i = 0; i < scs.Length; ++i)
            {
                if (CSID != int.Parse(scs[i].ToString()))
                {
                    ++k2;
                }
                else
                {
                    break;
                }
            }
            //判断是否是首车
            bool mark = true;   //若是首车，则mark为true
            for (int i = 0; i < k; ++i)   //遍历申请车辆之前的所有车
            {
                for (int j = 0; j < k2; ++j)  //遍历包含所申请临界区之前的所有临界区
                {
                    string pre_scs = LaneQueue[LaneID].ElementAt(i).Original_SectionID;
                    if (pre_scs.Contains(scs[j].ToString()) == true)//前车包含本车所要申请的临界区，此时需判断前车是否已经离开该临界区
                    {
                        if (LaneQueue[LaneID].ElementAt(i).Left[CSID] == true)  //前车已离开该临界区，本车已可申请该临界区
                        {

                        }
                        else
                        {
                            mark = false;
                        }
                    }
                    else    //前车未包含本车所要申请的临界区，此时无需判断前车是否已经离开该临界区
                    {

                    }
                }
            }

            if (mark == true)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /************************************************************************/
        /* 判断是否会出现死锁，返回True则死锁产生                                                                     */
        /************************************************************************/
        private bool isTokenSequenceDeadLock(Dictionary<int, string> SQ)
        {
            int i, j;
            int Count = 0;
            int[] array = new int[5];
            SuperVehicleManager[] svm = new SuperVehicleManager[SQ.Count];

            for (i = 0; i < 5; i++)
            {
                for (j = 0; j < 5; j++)
                {
                    this.SourceGraph[i, j] = false;
                }
                this.Walked[i] = false;
            }

            //获取待授权的所有车辆的车辆superManager信息，存入svm中
            for (i = 0; i < SQ.Count; i++)
            {
                string SQTemp = SQ.ElementAt(i).ToString(); //车辆ID
                string VehicleID = SQTemp.Substring(4, SQTemp.Count()-5);
                
                Vehicle VehicleTemp = FindVehicleByID(VehicleID);      //车辆对象
                string LaneIDTemp = VehicleTemp.Get_Current_LaneID();  //车辆所在LaneID

                for (j = 0; j < this.LaneQueue[int.Parse(LaneIDTemp.ElementAt(5).ToString())].Count; j++)
                {                  
                    //需要修改
                    if (this.LaneQueue[int.Parse(LaneIDTemp.ElementAt(5).ToString())].ElementAt(j).ID == SQ.ElementAt(i).Value)
                    {
                        svm[Count] = this.LaneQueue[int.Parse(LaneIDTemp.ElementAt(5).ToString())].ElementAt(j);
                        Count++;
                        break;
                    }
                }
            }

            //构建资源分配表
            for (i = 0; (i + 3) < 7; ++i)
            {//临界区标号
                for (j = 0; j < Count; j++)
                {//车辆数目
                    if (int.Parse(svm[j].SectionID[i].ToString()) != 0)
                    {
                        if (svm[j].Left[int.Parse(svm[j].SectionID[i].ToString())] == false)
                        {//若该临界区未走过，则将其下面要走的路径标志为true
                            if (int.Parse(svm[j].SectionID[i + 1].ToString()) != 0)
                            {
                                this.SourceGraph[int.Parse(svm[j].SectionID[i].ToString()), int.Parse(svm[j].SectionID[i + 1].ToString())] = true;
                            }
                            if (int.Parse(svm[j].SectionID[i + 2].ToString()) != 0)
                            {
                                this.SourceGraph[int.Parse(svm[j].SectionID[i + 1].ToString()), int.Parse(svm[j].SectionID[i + 2].ToString())] = true;
                            }
                            if (int.Parse(svm[j].SectionID[i + 3].ToString()) != 0)
                            {
                                this.SourceGraph[int.Parse(svm[j].SectionID[i + 2].ToString()), int.Parse(svm[j].SectionID[i + 3].ToString())] = true;
                            }
                        }
                        else
                        {//如果车辆已离开该临界区则无需在将临界区加入继续判断是否会死锁
                            /*                            Debug.WriteLine("fdasfsd");*/
                        }
                    }
                    else
                    {//若车辆为经过该临界区

                    }
                }
            }

            //检查是否有回路出现
            for (i = 1; i <= 4; i++)
            {
                //从第一个临界区开始检测，通过递归的方式，检测其所需要的临界区是否被走过，
                //若走过，那么就会出现环路
                if (dfsCheckCircuit(i))
                {
                    return true;
                }
            }
            return false;
        }

        /************************************************************************/
        /* 检测资源是否出现环路，若返回true，则产生了回路 
         * 1、若该临界区被走过，则说明产生了回路
         * 2、若未被走过，则判断其所需的下一临界区
         */
        /************************************************************************/
        private bool dfsCheckCircuit(int current)
        {
            if (Walked[current])
            {
                return true;
            }
            Walked[current] = true;
            for (int i = 1; i <= 4; i++)
            {
                if (this.SourceGraph[current, i])
                {
                    //若箭头存在，即该临界区需求下一临界区
                    //则继续判断该临界区是否会出现回路
                    if (dfsCheckCircuit(i))
                    {
                        return true;
                    }
                }
            }
            Walked[current] = false;
            return false;
        }



        /************************************************************************/
        /* 发送临界区授权信息                                                                     */
        /************************************************************************/
        private void sendMessage(int Type, String ID, int Priority, int CSID, Intersection Intersection)
        {
            this.MsgCount++;
            float[] ts = new float[5];
            float[] te = new float[5];
            switch (Type)
            {
                case Definitions.MsgAuthorize:
                    Message m = new Message(Definitions.MsgAuthorize, Definitions.Agent, ID,
                            ts, te, -1.0f, Priority, CSID.ToString(), -1,"");//""站位

                    //Test将授权信息全部写入到文件中
                    //TsetRecordMessageInformation(m);
                    //string text = System.IO.File.ReadAllText(@"D:\IOTest\IOTest1.txt");
                    //text += Intersection.GetID() + " " + m.GetLaneID() + " " + m.GetReceiver() + " " + m.GetSectionID() + "\r\n";
                    //System.IO.File.WriteAllText(@"D:\IOTest\IOTest1.txt", text);

                    //写到消息队列
                    List<Message> AtoV_BufferTemp = Intersection.GetAtoV_Buffer();
                    AtoV_BufferTemp.Add(m);
                    Intersection.SetAtoV_Buffer(AtoV_BufferTemp);
                    MainData.UpdateIntersectionList(Intersection);

                    this.Token[CSID] = true;
                    // this.OutPutAuthMsg(1, m);
                    break;
                case Definitions.MsgRefuse:
                    break;
                default:
                    System.Windows.Forms.MessageBox.Show("Message Type is wrong ---- " + Type, "Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    return;
            }
        }

        /************************************************************************/
        /* 设置授权信息，TokenID为被授权的临界区号，ID是被授权车辆                                                                     */
        /************************************************************************/
        private void setToken(int TokenID, string ID)
        {
            //返回ID信息不够，返回车辆Vehicle对象  xc
            Vehicle Vehicle = FindVehicleByID(ID);
            string LaneID = Vehicle.Get_Current_LaneID();

            int j = 0;
            for (j = 0; j < this.LaneQueue[int.Parse(LaneID[5].ToString())].Count; j++)
            {
                if (this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).ID == ID)
                {
                    //LaneQueue中存储的信息
                    this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).HaveTokenCount++;
                    this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).Token[TokenID] = true;
                    this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).VehicleManagers[TokenID].HasToken = true;
                    for (int i = 0; i < 5; i++)
                    {
                        if (this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).VehicleManagers[i] != null)
                        {
                            this.LaneQueue[int.Parse(LaneID[5].ToString())].ElementAt(j).VehicleManagers[i].Token[TokenID] = true;
                        }
                    }
                }
            }

            //CS中存储的信息
            foreach (KeyValuePair<string, VehicleManager> kvp in this.CS[TokenID])
            {
                if (kvp.Key == ID)
                {
                    kvp.Value.HasToken = true;
                    kvp.Value.Token[TokenID] = true;
                }
            }
            for (int i = 0; i < 5; ++i)
            {
                foreach (KeyValuePair<string, VehicleManager> kvp in this.CS[i])
                {
                    if (kvp.Key == ID)
                    {
                        kvp.Value.Token[TokenID] = true;
                    }
                }
            }

            //本文件中的车道标志信息
            this.Token[TokenID] = true;
            return;
        }

        //获取ID
        public string GetID() 
        {
            return this.ID;
        }

        //设置ID
        public void SetID(string ID) 
        {
            this.ID = ID;
        }

        //获取Num
        public int GetIDNum()
        {
            return this.IDNum;
        }

        //设置Num
        public void SetIDNum(int IDNum) 
        {
            this.IDNum = IDNum;
        }

        //获取授权信息
        public Dictionary<int, string> GetAuthorize_CS_to_Vehicle()
        {
            return this.Authorize_CS_to_Vehicle;
        }


        //根据ID在全局的VehicleList中找到Vehicle
        public static Vehicle FindVehicleByID(string ID)
        {
            Vehicle Vehicle = new Vehicle();
            for (int i = 0; i < MainData.Map.GlobalVehicleList.Count(); i++)
            {
                Vehicle veh = MainData.Map.GlobalVehicleList[i];
                if (veh.Get_ID() == ID)
                {
                    Vehicle = veh;
                }
            }
            return Vehicle;
        }

    }
}
